import tkinter as tk
from tkinter import messagebox, ttk  # !!! 新增ttk导入
import json
import bcrypt
import os
from datetime import datetime
import random
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import warnings

warnings.filterwarnings("ignore", category=UserWarning, message=".*iCCP.*")

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


# ------------------ 屏幕尺寸计算 ------------------
class ScreenMetrics:
    def __init__(self):
        self.root = tk.Tk()
        self.root.withdraw()
        self.screen_width = self.root.winfo_screenwidth()
        self.screen_height = self.root.winfo_screenheight()
        self.base_width = 1920  # 设计基准宽度
        self.base_height = 1080  # 设计基准高度
        self.scale_w = self.screen_width / self.base_width
        self.scale_h = self.screen_height / self.base_height
        self.scale = min(self.scale_w, self.scale_h)
        self.root.destroy()


metrics = ScreenMetrics()


# ------------------ 自适应字体 ------------------
def get_font(size, style=None):
    base_font = ("SimSun", int(size * metrics.scale))
    if style:
        return (base_font[0], base_font[1], style)
    return base_font


BASE_FONT = get_font(12)
TITLE_FONT = get_font(16, "bold")
BUTTON_FONT = get_font(14)


# ------------------ 全局变量初始化 ------------------
current_user = None  # 当前登录用户


# ------------------ 辅助函数 ------------------
def ensure_training_data_folder():
    if not os.path.exists("training_data"):
        os.makedirs("training_data")


def load_user_training_data(username):
    ensure_training_data_folder()
    file_path = f"training_data/training_data_{username}.json"
    if not os.path.exists(file_path):
        with open(file_path, "w") as file:
            json.dump([], file)
    with open(file_path, "r") as file:
        return json.load(file)


def save_user_training_data(username, data):
    ensure_training_data_folder()
    file_path = f"training_data/training_data_{username}.json"
    with open(file_path, "w") as file:
        json.dump(data, file, indent=4)


# !!! 修改记录函数添加题型参数
def record_user_training(username, word, correct, user_answer=None, question=None, question_type=None):
    data = load_user_training_data(username)
    record = {
        "word": word,
        "question": question,
        "correct": correct,
        "user_answer": user_answer,
        "question_type": question_type,  # 新增题型字段
        "timestamp": datetime.now().isoformat()
    }
    data.append(record)
    save_user_training_data(username, data)


def load_users(file_path="users.json"):
    if not os.path.exists(file_path):
        with open(file_path, "w") as file:
            json.dump({}, file)
    with open(file_path, "r") as file:
        return json.load(file)


def save_users(users, file_path="users.json"):
    with open(file_path, "w") as file:
        json.dump(users, file, indent=4)


def load_cet4_words(folder_path="cet-4_json"):
    word_list = []
    for file_name in os.listdir(folder_path):
        if file_name.endswith(".json"):
            file_path = os.path.join(folder_path, file_name)
            with open(file_path, "r", encoding="utf-8") as file:
                data = json.load(file)
                word_list.extend(data)
    return word_list


# ------------------ 全屏管理 ------------------
def toggle_fullscreen(event=None):
    root.attributes("-fullscreen", not root.attributes("-fullscreen"))


def end_fullscreen(event=None):
    root.attributes("-fullscreen", False)


# ------------------ 忘记密码功能 ------------------
def forgot_password():
    def update_password():
        username = username_entry.get().strip()
        new_password = new_password_entry.get().strip()
        confirm_password = confirm_password_entry.get().strip()

        if not username or not new_password or not confirm_password:
            messagebox.showerror("错误", "所有字段必须填写！")
            return

        if new_password != confirm_password:
            messagebox.showerror("错误", "新密码与确认密码不一致！")
            return

        users = load_users()
        if username not in users:
            messagebox.showerror("错误", "用户名不存在！")
            return

        hashed_password = bcrypt.hashpw(new_password.encode('utf-8'), bcrypt.gensalt())
        users[username]["password"] = hashed_password.decode('utf-8')
        save_users(users)
        messagebox.showinfo("成功", "密码更新成功！")
        forgot_window.destroy()

    forgot_window = tk.Toplevel(root)
    forgot_window.attributes("-fullscreen", True)
    forgot_window.title("重置密码")

    main_frame = tk.Frame(forgot_window)
    main_frame.pack(expand=True, fill=tk.BOTH, padx=int(100 * metrics.scale), pady=int(100 * metrics.scale))

    tk.Label(main_frame, text="重置密码", font=TITLE_FONT).pack(pady=int(40 * metrics.scale))

    input_frame = tk.Frame(main_frame)
    input_frame.pack(pady=int(40 * metrics.scale))

    tk.Label(input_frame, text="用户名:", font=BASE_FONT).grid(row=0, column=0, padx=int(20 * metrics.scale),
                                                               pady=int(10 * metrics.scale))
    username_entry = tk.Entry(input_frame, font=BASE_FONT)
    username_entry.grid(row=0, column=1, padx=int(20 * metrics.scale), pady=int(10 * metrics.scale))

    tk.Label(input_frame, text="新密码:", font=BASE_FONT).grid(row=1, column=0, padx=int(20 * metrics.scale),
                                                               pady=int(10 * metrics.scale))
    new_password_entry = tk.Entry(input_frame, show="*", font=BASE_FONT)
    new_password_entry.grid(row=1, column=1, padx=int(20 * metrics.scale), pady=int(10 * metrics.scale))

    tk.Label(input_frame, text="确认密码:", font=BASE_FONT).grid(row=2, column=0, padx=int(20 * metrics.scale),
                                                                 pady=int(10 * metrics.scale))
    confirm_password_entry = tk.Entry(input_frame, show="*", font=BASE_FONT)
    confirm_password_entry.grid(row=2, column=1, padx=int(20 * metrics.scale), pady=int(10 * metrics.scale))

    button_frame = tk.Frame(main_frame)
    button_frame.pack(pady=int(40 * metrics.scale))
    tk.Button(button_frame, text="更新密码", font=BUTTON_FONT,
              command=update_password).pack(side=tk.LEFT, padx=int(20 * metrics.scale))


# ------------------ 训练记录可视化 ------------------
def show_training_stats(parent_window=None):
    if parent_window:
        parent_window.withdraw()

    stats_window = tk.Toplevel(root)
    stats_window.attributes("-fullscreen", True)
    stats_window.title("训练记录")
    stats_window.configure(bg="white")

    main_frame = tk.Frame(stats_window, bg="white")
    main_frame.pack(expand=True, fill=tk.BOTH, padx=int(100 * metrics.scale), pady=int(50 * metrics.scale))

    left_frame = tk.Frame(main_frame, bg="white", width=int(400 * metrics.scale))
    left_frame.pack(side=tk.LEFT, fill=tk.BOTH, padx=int(20 * metrics.scale))

    data = load_user_training_data(current_user)
    total_count = len(data)
    correct_count = sum(1 for r in data if r["correct"])
    incorrect_count = total_count - correct_count
    accuracy = (correct_count / total_count) * 100 if total_count else 0
    
    # 按题型统计正确率
    choice_data = [r for r in data if r.get("question_type") == "选择题"]
    spelling_data = [r for r in data if r.get("question_type") == "拼写题"]
    
    choice_total = len(choice_data)
    choice_correct = sum(1 for r in choice_data if r["correct"])
    choice_accuracy = (choice_correct / choice_total) * 100 if choice_total else 0
    
    spelling_total = len(spelling_data)
    spelling_correct = sum(1 for r in spelling_data if r["correct"])
    spelling_accuracy = (spelling_correct / spelling_total) * 100 if spelling_total else 0

    fig = plt.figure(figsize=(6 * metrics.scale, 6 * metrics.scale), facecolor='white')
    ax = fig.add_subplot(111)
    if total_count > 0:
        sizes = [correct_count, incorrect_count]
        labels = [f'正确 ({correct_count})', f'错误 ({incorrect_count})']
        colors = ['#67C23A', '#F56C6C']
        explode = (0.05, 0)
        ax.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%',
               startangle=90, explode=explode, wedgeprops={'linewidth': 1, 'edgecolor': 'white'})
        ax.axis('equal')

    chart_canvas = FigureCanvasTkAgg(fig, master=left_frame)
    chart_canvas.draw()
    chart_canvas.get_tk_widget().pack(pady=int(20 * metrics.scale), fill=tk.BOTH, expand=True)
    
    # 显示各题型统计信息
    stats_text = (
        f"总答题数：{total_count}  总正确率：{accuracy:.2f}%\n"
        f"选择题：{choice_total}题  正确率：{choice_accuracy:.2f}%\n"
        f"拼写题：{spelling_total}题  正确率：{spelling_accuracy:.2f}%"
    )
    tk.Label(left_frame, text=stats_text, font=get_font(12), 
             bg="white", fg="#666666", justify=tk.LEFT).pack(pady=int(20 * metrics.scale))

    right_frame = tk.Frame(main_frame, bg="white")
    right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)

    stats_header = tk.Frame(right_frame, bg="white")
    stats_header.pack(fill=tk.X, pady=int(20 * metrics.scale))

    tk.Label(stats_header, text=f"训练记录", font=get_font(14, "bold"),
             bg="white", fg="#333333").pack(side=tk.LEFT)

    scroll_container = tk.Frame(right_frame, bg="white")
    scroll_container.pack(fill=tk.BOTH, expand=True)

    canvas = tk.Canvas(scroll_container, bg="white", highlightthickness=0)
    scrollbar = tk.Scrollbar(scroll_container, orient=tk.VERTICAL, command=canvas.yview)
    content_frame = tk.Frame(canvas, bg="white")

    canvas.configure(yscrollcommand=scrollbar.set)
    canvas.create_window((0, 0), window=content_frame, anchor=tk.NW)
    content_frame.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))

    canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
    scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

    for idx, record in enumerate(data):
        bg_color = "#F8F9FA" if idx % 2 == 0 else "white"
        parts = [
            f"[{datetime.fromisoformat(record['timestamp']).strftime('%Y-%m-%d')}]",
            f"类型：{record.get('question_type', '未知')}",
            f"题目：{record['question']}",
            f"单词：{record['word']}",
            f"答案：{record['user_answer']}" if record.get("user_answer") else ""
        ]
        display_text = " | ".join(filter(None, parts))
        status_text = "正确" if record["correct"] else "错误"
        status_color = "#67C23A" if record["correct"] else "#F56C6C"

        record_frame = tk.Frame(content_frame, bg=bg_color)
        record_frame.pack(fill=tk.X, pady=1)

        tk.Label(record_frame, text=display_text, font=get_font(12),
                 bg=bg_color, fg="#333333", anchor=tk.W).pack(side=tk.LEFT, padx=int(15 * metrics.scale),
                                                              pady=int(8 * metrics.scale), expand=True)
        tk.Label(record_frame, text=status_text, font=get_font(12, "bold"),
                 bg=bg_color, fg=status_color).pack(side=tk.RIGHT, padx=int(15 * metrics.scale))

    btn_frame = tk.Frame(right_frame, bg="white")
    btn_frame.pack(fill=tk.X, pady=int(20 * metrics.scale))
    
    # 添加返回主菜单按钮
    tk.Button(btn_frame, text="返回主菜单", font=get_font(14, "bold"),
              bg="#409EFF", fg="white", padx=int(30 * metrics.scale), pady=int(8 * metrics.scale),
              command=lambda: [stats_window.destroy(), open_game_menu()]).pack(side=tk.LEFT)
    
    # 原有的返回按钮（返回上一级菜单）
    tk.Button(btn_frame, text="返回", font=get_font(14, "bold"),
              bg="#F56C6C", fg="white", padx=int(30 * metrics.scale), pady=int(8 * metrics.scale),
              command=lambda: [stats_window.destroy(), parent_window.deiconify()]).pack(side=tk.RIGHT)


# ------------------ 智能错题本功能 ------------------
def show_incorrect_answers(parent_window):
    """显示智能错题本界面"""
    if parent_window:
        parent_window.withdraw()
    
    error_window = tk.Toplevel(root)
    error_window.attributes("-fullscreen", True)
    error_window.title("智能错题本")
    
    main_frame = tk.Frame(error_window)
    main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))
    
    tk.Label(main_frame, text="📚 智能错题本", font=TITLE_FONT).pack(pady=int(20 * metrics.scale))
    
    # 创建滚动区域
    scroll_container = tk.Frame(main_frame)
    scroll_container.pack(fill=tk.BOTH, expand=True, pady=int(20 * metrics.scale))
    
    canvas = tk.Canvas(scroll_container, bg="white", highlightthickness=0)
    scrollbar = tk.Scrollbar(scroll_container, orient=tk.VERTICAL, command=canvas.yview)
    content_frame = tk.Frame(canvas, bg="white")
    
    canvas.configure(yscrollcommand=scrollbar.set)
    canvas.create_window((0, 0), window=content_frame, anchor=tk.NW)
    content_frame.bind("<Configure>", lambda e: canvas.configure(scrollregion=canvas.bbox("all")))
    
    canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
    scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
    
    try:
        error_words = get_review_words(current_user, limit=50)
        
        if not error_words:
            tk.Label(content_frame, text="🎉 暂无错题记录，继续加油学习！", 
                    font=get_font(16), fg="#67C23A", bg="white").pack(pady=int(40 * metrics.scale))
        else:
            # 显示错题统计信息
            tk.Label(content_frame, text=f"📊 发现 {len(error_words)} 个需要重点复习的单词", 
                    font=get_font(14), fg="#E6A23C", bg="white").pack(pady=int(10 * metrics.scale))
            
            # 按错误次数分组显示
            high_priority = [w for w in error_words if w['error_count'] >= 3]
            medium_priority = [w for w in error_words if w['error_count'] == 2]
            low_priority = [w for w in error_words if w['error_count'] == 1]
            
            if high_priority:
                tk.Label(content_frame, text="🔴 高错误率单词 (错误3次以上):", 
                        font=get_font(12, "bold"), fg="#F56C6C", bg="white").pack(pady=(int(20 * metrics.scale), int(5 * metrics.scale)), anchor=tk.W)
                for word_info in high_priority:
                    word_text = f"  • {word_info['word']} (错误 {word_info['error_count']} 次)"
                    tk.Label(content_frame, text=word_text, font=get_font(11), 
                            fg="#F56C6C", bg="white").pack(pady=int(2 * metrics.scale), anchor=tk.W)
            
            if medium_priority:
                tk.Label(content_frame, text="🟡 中等错误率单词 (错误2次):", 
                        font=get_font(12, "bold"), fg="#E6A23C", bg="white").pack(pady=(int(15 * metrics.scale), int(5 * metrics.scale)), anchor=tk.W)
                for word_info in medium_priority:
                    word_text = f"  • {word_info['word']} (错误 {word_info['error_count']} 次)"
                    tk.Label(content_frame, text=word_text, font=get_font(11), 
                            fg="#E6A23C", bg="white").pack(pady=int(2 * metrics.scale), anchor=tk.W)
            
            if low_priority:
                tk.Label(content_frame, text="🟢 低错误率单词 (错误1次):", 
                        font=get_font(12, "bold"), fg="#909399", bg="white").pack(pady=(int(15 * metrics.scale), int(5 * metrics.scale)), anchor=tk.W)
                for word_info in low_priority:
                    word_text = f"  • {word_info['word']} (错误 {word_info['error_count']} 次)"
                    tk.Label(content_frame, text=word_text, font=get_font(11), 
                            fg="#909399", bg="white").pack(pady=int(2 * metrics.scale), anchor=tk.W)
                    
            # 重点复习按钮
            if error_words:
                btn_review_frame = tk.Frame(content_frame, bg="white")
                btn_review_frame.pack(pady=int(30 * metrics.scale))
                
                tk.Button(btn_review_frame, text="开始重点复习", font=BUTTON_FONT, 
                         bg="#E6A23C", fg="white", padx=int(30 * metrics.scale), pady=int(8 * metrics.scale),
                         command=lambda: start_error_review_mode(error_words, error_window)).pack()
                
    except Exception as e:
        tk.Label(content_frame, text=f"加载错题数据时出现问题: {str(e)}", 
                font=get_font(16), fg="#F56C6C", bg="white").pack(pady=int(40 * metrics.scale))
    
    btn_frame = tk.Frame(main_frame)
    btn_frame.pack(pady=int(20 * metrics.scale))
    tk.Button(btn_frame, text="返回主菜单", font=BUTTON_FONT, bg="#409EFF", fg="white",
              command=lambda: [error_window.destroy(), open_game_menu()]).pack()


def show_learning_status(parent_window):
    """显示学习状态分析界面"""
    if parent_window:
        parent_window.withdraw()
    
    status_window = tk.Toplevel(root)
    status_window.attributes("-fullscreen", True)
    status_window.title("学习状态分析")
    
    main_frame = tk.Frame(status_window)
    main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))
    
    tk.Label(main_frame, text="📊 学习状态分析", font=TITLE_FONT).pack(pady=int(20 * metrics.scale))
    
    try:
        word_status = load_word_status(current_user)
        training_data = load_user_training_data(current_user)
        
        if word_status:
            total_words = len(word_status)
            mastered_words = sum(1 for s in word_status.values() if s["mastered"])
            error_words = sum(1 for s in word_status.values() if s["error_count"] > 0)
            mastery_rate = (mastered_words / total_words * 100) if total_words > 0 else 0
            
            # 获取最近7天的学习记录
            from datetime import datetime, timedelta
            now = datetime.now()
            recent_records = []
            for record in training_data:
                try:
                    record_time = datetime.fromisoformat(record['timestamp'])
                    if (now - record_time).days <= 7:
                        recent_records.append(record)
                except:
                    continue
            
            recent_correct = sum(1 for r in recent_records if r['correct'])
            recent_total = len(recent_records)
            recent_accuracy = (recent_correct / recent_total * 100) if recent_total > 0 else 0
            
            # 创建左右两列布局
            content_frame = tk.Frame(main_frame)
            content_frame.pack(fill=tk.BOTH, expand=True, pady=int(20 * metrics.scale))
            
            left_frame = tk.Frame(content_frame)
            left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=int(20 * metrics.scale))
            
            right_frame = tk.Frame(content_frame)
            right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=int(20 * metrics.scale))
            
            # 左侧 - 基本统计
            tk.Label(left_frame, text="📈 基本学习统计", font=get_font(14, "bold")).pack(anchor=tk.W, pady=int(10 * metrics.scale))
            
            stats_text = f"""
• 总学习单词：{total_words} 个
• 已熟练掌握：{mastered_words} 个  
• 掌握率：{mastery_rate:.1f}%
• 有错误记录：{error_words} 个
• 总答题次数：{len(training_data)} 题
• 总体正确率：{(sum(1 for r in training_data if r['correct']) / len(training_data) * 100):.1f}%
            """
            
            tk.Label(left_frame, text=stats_text, font=get_font(12), justify=tk.LEFT).pack(anchor=tk.W, pady=int(10 * metrics.scale))
            
            # 右侧 - 最近表现
            tk.Label(right_frame, text="📅 最近7天表现", font=get_font(14, "bold")).pack(anchor=tk.W, pady=int(10 * metrics.scale))
            
            recent_text = f"""
• 答题次数：{recent_total} 题
• 正确次数：{recent_correct} 题
• 最近正确率：{recent_accuracy:.1f}%
            """
            
            if recent_total > 0:
                if recent_accuracy >= 80:
                    performance_text = "🎉 表现优秀！"
                    performance_color = "#67C23A"
                elif recent_accuracy >= 60:
                    performance_text = "👍 表现良好"
                    performance_color = "#409EFF"
                else:
                    performance_text = "💪 需要加强"
                    performance_color = "#E6A23C"
                
                recent_text += f"\n• 学习状态：{performance_text}"
            else:
                recent_text += "\n• 学习状态：暂无最近记录"
                performance_color = "#909399"
            
            tk.Label(right_frame, text=recent_text, font=get_font(12), justify=tk.LEFT, fg=performance_color).pack(anchor=tk.W, pady=int(10 * metrics.scale))
            
            # 题型分析
            choice_records = [r for r in training_data if r.get("question_type") == "选择题"]
            spelling_records = [r for r in training_data if r.get("question_type") == "拼写题"]
            
            if choice_records or spelling_records:
                analysis_frame = tk.Frame(main_frame)
                analysis_frame.pack(pady=int(20 * metrics.scale))
                
                tk.Label(analysis_frame, text="📋 题型表现分析", font=get_font(14, "bold")).pack(pady=int(10 * metrics.scale))
                
                if choice_records:
                    choice_correct = sum(1 for r in choice_records if r['correct'])
                    choice_accuracy = (choice_correct / len(choice_records) * 100)
                    tk.Label(analysis_frame, text=f"选择题：{len(choice_records)}题，正确率 {choice_accuracy:.1f}%", 
                            font=get_font(12)).pack()
                
                if spelling_records:
                    spelling_correct = sum(1 for r in spelling_records if r['correct'])
                    spelling_accuracy = (spelling_correct / len(spelling_records) * 100)
                    tk.Label(analysis_frame, text=f"拼写题：{len(spelling_records)}题，正确率 {spelling_accuracy:.1f}%", 
                            font=get_font(12)).pack()
            
        else:
            tk.Label(main_frame, text="📚 还没有学习数据，开始你的第一次练习吧！", 
                    font=get_font(16), fg="#409EFF").pack(pady=int(40 * metrics.scale))
            
    except Exception as e:
        tk.Label(main_frame, text=f"加载学习状态时出现问题: {str(e)}", 
                font=get_font(16), fg="#F56C6C").pack(pady=int(40 * metrics.scale))
    
    btn_frame = tk.Frame(main_frame)
    btn_frame.pack(pady=int(20 * metrics.scale))
    tk.Button(btn_frame, text="返回主菜单", font=BUTTON_FONT, bg="#409EFF", fg="white",
              command=lambda: [status_window.destroy(), open_game_menu()]).pack()


def check_spelling_answer_with_feedback(user_input, correct_word, show_feedback_func):
    """拼写答案检查（带反馈）- 用于闯关模式"""
    user_input = user_input.strip()
    
    if user_input.lower() == correct_word.lower():
        messagebox.showinfo("结果", "拼写正确！")
        return True
    else:
        try:
            show_feedback_func(user_input, correct_word)
        except:
            pass
        messagebox.showerror("拼写错误", f"拼写错误！正确答案：{correct_word}")
        return False


# ------------------ 主功能菜单 ------------------
def open_game_menu(parent=None):
    if parent:
        parent.withdraw()

    game_menu = tk.Toplevel(root)
    game_menu.attributes("-fullscreen", True)
    game_menu.title("功能选择界面")

    main_frame = tk.Frame(game_menu)
    main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))

    header_frame = tk.Frame(main_frame)
    header_frame.pack(pady=int(60 * metrics.scale))
    tk.Label(header_frame, text=f"欢迎 {current_user}！请选择学习功能", font=TITLE_FONT).pack()
    
    # 显示学习状态概览
    status_data = load_word_status(current_user)
    if status_data:
        total_words = len(status_data)
        mastered_words = sum(1 for s in status_data.values() if s["mastered"])
        error_words = sum(1 for s in status_data.values() if s["error_count"] > 0)
        mastery_rate = (mastered_words / total_words * 100) if total_words > 0 else 0
        
        status_text = f"学习进度：已掌握 {mastered_words}/{total_words} 个单词 ({mastery_rate:.1f}%) | 错题 {error_words} 个"
        tk.Label(header_frame, text=status_text, font=get_font(12), fg="#666666").pack(pady=int(10 * metrics.scale))

    button_frame = tk.Frame(main_frame)
    button_frame.pack(pady=int(60 * metrics.scale))

    buttons = [
        ("单词选择题", lambda: start_choice_quiz(game_menu)),
        ("拼写填空", lambda: start_spelling_quiz(game_menu)),
        ("智能错题本", lambda: show_incorrect_answers(game_menu)),
        ("学习状态", lambda: show_learning_status(game_menu)),
        ("单词闯关打卡", lambda: start_word_challenge(game_menu))
    ]

    for text, command in buttons:
        btn = tk.Button(button_frame, text=text, font=BUTTON_FONT,
                        command=command, width=int(20 * metrics.scale),
                        height=int(2 * metrics.scale))
        btn.pack(pady=int(20 * metrics.scale))

    tk.Button(main_frame, text="退出系统", font=BUTTON_FONT,
              command=lambda: [game_menu.destroy(), root.destroy()]).pack(pady=int(40 * metrics.scale))







# ------------------ 注册功能 ------------------
def register_user():
    register_window = tk.Toplevel(root)
    register_window.attributes("-fullscreen", True)
    register_window.title("用户注册")

    main_frame = tk.Frame(register_window)
    main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))

    tk.Label(main_frame, text="用户注册", font=TITLE_FONT).pack(pady=int(60 * metrics.scale))

    input_frame = tk.Frame(main_frame)
    input_frame.pack(pady=int(40 * metrics.scale))

    tk.Label(input_frame, text="用户名:", font=BASE_FONT).grid(row=0, column=0,
                                                               padx=int(20 * metrics.scale),
                                                               pady=int(20 * metrics.scale))
    username_entry = tk.Entry(input_frame, font=BASE_FONT)
    username_entry.grid(row=0, column=1, padx=int(20 * metrics.scale), pady=int(20 * metrics.scale))

    tk.Label(input_frame, text="密码:", font=BASE_FONT).grid(row=1, column=0,
                                                             padx=int(20 * metrics.scale),
                                                             pady=int(20 * metrics.scale))
    password_entry = tk.Entry(input_frame, show="*", font=BASE_FONT)
    password_entry.grid(row=1, column=1, padx=int(20 * metrics.scale), pady=int(20 * metrics.scale))

    def handle_register():
        username = username_entry.get().strip()
        password = password_entry.get().strip()

        if not username or not password:
            messagebox.showerror("错误", "用户名和密码不能为空！")
            return

        users = load_users()
        if username in users:
            messagebox.showerror("错误", "用户名已存在！")
        else:
            hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
            users[username] = {"password": hashed_password.decode('utf-8')}
            save_users(users)
            messagebox.showinfo("成功", "注册成功！")
            register_window.destroy()

    btn_frame = tk.Frame(main_frame)
    btn_frame.pack(pady=int(40 * metrics.scale))
    tk.Button(btn_frame, text="注册", font=BUTTON_FONT,
              command=handle_register).pack(pady=int(20 * metrics.scale))






# ------------------ 登录功能 ------------------
def login_user():
    login_window = tk.Toplevel(root)
    login_window.attributes("-fullscreen", True)
    login_window.title("用户登录")

    main_frame = tk.Frame(login_window)
    main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))

    tk.Label(main_frame, text="用户登录", font=TITLE_FONT).pack(pady=int(60 * metrics.scale))

    input_frame = tk.Frame(main_frame)
    input_frame.pack(pady=int(40 * metrics.scale))

    tk.Label(input_frame, text="用户名:", font=BASE_FONT).grid(row=0, column=0,
                                                               padx=int(20 * metrics.scale),
                                                               pady=int(20 * metrics.scale))
    username_entry = tk.Entry(input_frame, font=BASE_FONT)
    username_entry.grid(row=0, column=1, padx=int(20 * metrics.scale), pady=int(20 * metrics.scale))

    tk.Label(input_frame, text="密码:", font=BASE_FONT).grid(row=1, column=0,
                                                             padx=int(20 * metrics.scale),
                                                             pady=int(20 * metrics.scale))
    password_entry = tk.Entry(input_frame, show="*", font=BASE_FONT)
    password_entry.grid(row=1, column=1, padx=int(20 * metrics.scale), pady=int(20 * metrics.scale))

    def handle_login():
        global current_user
        username = username_entry.get().strip()
        password = password_entry.get().strip()

        if not username or not password:
            messagebox.showerror("错误", "用户名和密码不能为空！")
            return

        users = load_users()
        if username in users:
            hashed_password = users[username]["password"].encode('utf-8')
            if bcrypt.checkpw(password.encode('utf-8'), hashed_password):
                current_user = username
                messagebox.showinfo("成功", f"欢迎 {username}！")
                login_window.destroy()
                root.withdraw()
                open_game_menu()
            else:
                messagebox.showerror("错误", "密码错误！")
        else:
            messagebox.showerror("错误", "用户名不存在！")

    btn_frame = tk.Frame(main_frame)
    btn_frame.pack(pady=int(40 * metrics.scale))
    tk.Button(btn_frame, text="登录", font=BUTTON_FONT,
              command=handle_login).pack(pady=int(20 * metrics.scale))







# ------------------ 核心训练功能 ------------------
def start_choice_quiz(parent_window=None):
    if parent_window:
        parent_window.withdraw()

    quiz_window = tk.Toplevel(root)
    quiz_window.attributes("-fullscreen", True)
    quiz_window.title("单词选择题")

    folder_path = "cet-4_json"
    all_words = load_cet4_words(folder_path)
    # 使用自适应单词选择
    words = get_adaptive_word_list(current_user, all_words, 50)
    random.shuffle(words)

    def next_question():
        nonlocal words
        if not words:
            # 显示完成总结
            show_choice_completion_summary()
            return

        question = words.pop()
        correct_word = question["word"]
        question_text = question["mean"]
        
        # 获取当前单词的学习状态
        word_status = load_word_status(current_user).get(correct_word, {})
        error_count = word_status.get("error_count", 0)
        
        # 从剩余单词中选择干扰项，如果剩余单词不足，从所有单词中选择
        remaining_words = words if len(words) >= 3 else all_words
        options = [correct_word] + [random.choice([w for w in remaining_words if w["word"] != correct_word])["word"] for _ in range(3)]
        random.shuffle(options)

        for widget in quiz_window.winfo_children():
            widget.destroy()

        main_frame = tk.Frame(quiz_window)
        main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))

        # 显示单词状态和进度信息
        status_frame = tk.Frame(main_frame)
        status_frame.pack(pady=int(20 * metrics.scale))
        
        progress_text = f"剩余单词: {len(words)} | 当前单词错误次数: {error_count}"
        tk.Label(status_frame, text=progress_text, font=get_font(12), fg="#666666").pack()

        header_frame = tk.Frame(main_frame)
        header_frame.pack(pady=int(60 * metrics.scale))
        
        tk.Label(header_frame, text=f"单词释义：{question_text}", font=TITLE_FONT).pack()

        options_frame = tk.Frame(main_frame)
        options_frame.pack(pady=int(60 * metrics.scale))

        def check_answer(selected_word):
            # 标准化输入，忽略大小写和首尾空格
            if selected_word.strip().lower() == correct_word.strip().lower():
                messagebox.showinfo("结果", "回答正确！")
                record_user_training(current_user, correct_word, True, selected_word, question_text, "选择题")
                # 更新单词状态为正确
                word_status = update_word_status(current_user, correct_word, True)
                
                # 检查是否已熟练
                if word_status["mastered"]:
                    messagebox.showinfo("恭喜", f"单词 '{correct_word}' 已熟练掌握！")
                    
            else:
                messagebox.showerror("结果", f"回答错误！正确答案是：{correct_word}")
                record_user_training(current_user, correct_word, False, selected_word, question_text, "选择题")
                # 更新单词状态为错误
                update_word_status(current_user, correct_word, False)
                
            next_question()

        for idx, option in enumerate(options):
            btn = tk.Button(options_frame, text=option, font=BUTTON_FONT,
                            width=int(20 * metrics.scale), height=int(2 * metrics.scale),
                            command=lambda opt=option: check_answer(opt))
            btn.grid(row=idx // 2, column=idx % 2, padx=int(30 * metrics.scale), pady=int(30 * metrics.scale))

        btn_frame = tk.Frame(main_frame)
        btn_frame.pack(pady=int(40 * metrics.scale))
        tk.Button(btn_frame, text="返回", font=BUTTON_FONT,
                  command=lambda: [quiz_window.destroy(), parent_window.deiconify()]).pack()

    def show_choice_completion_summary():
        """显示选择题完成总结"""
        for widget in quiz_window.winfo_children():
            widget.destroy()
        
        main_frame = tk.Frame(quiz_window)
        main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))
        
        tk.Label(main_frame, text="选择题训练完成！", font=TITLE_FONT).pack(pady=int(40 * metrics.scale))
        
        # 显示学习状态统计
        status_data = load_word_status(current_user)
        mastered_count = sum(1 for status in status_data.values() if status["mastered"])
        total_learned = len(status_data)
        
        stats_text = (
            f"已熟练单词：{mastered_count} 个\n"
            f"总学习单词：{total_learned} 个\n"
            f"掌握率：{(mastered_count/total_learned*100):.1f}%" if total_learned > 0 else "掌握率：0%"
        )
        
        tk.Label(main_frame, text=stats_text, font=get_font(16), justify=tk.CENTER).pack(pady=int(20 * metrics.scale))
        
        btn_frame = tk.Frame(main_frame)
        btn_frame.pack(pady=int(40 * metrics.scale))
        
        tk.Button(btn_frame, text="继续练习", font=BUTTON_FONT, bg="#409EFF", fg="white",
                  command=lambda: start_choice_quiz(parent_window)).pack(side=tk.LEFT, padx=int(20 * metrics.scale))
        tk.Button(btn_frame, text="返回主菜单", font=BUTTON_FONT,
                  command=lambda: [quiz_window.destroy(), open_game_menu()]).pack(side=tk.RIGHT, padx=int(20 * metrics.scale))

    next_question()




def start_spelling_quiz(parent_window=None):
    if parent_window:
        parent_window.withdraw()

    quiz_window = tk.Toplevel(root)
    quiz_window.attributes("-fullscreen", True)
    quiz_window.title("拼写填空")

    folder_path = "cet-4_json"
    all_words = load_cet4_words(folder_path)
    # 使用自适应单词选择
    words = get_adaptive_word_list(current_user, all_words, 50)
    random.shuffle(words)
    
    # 添加连续错误计数器和单词状态跟踪
    consecutive_errors = {}  # 字典存储每个单词的连续错误次数
    current_word_attempts = 0  # 当前单词的尝试次数
    max_attempts = 3  # 每个单词最多尝试3次

    def next_question():
        nonlocal words, current_word_attempts
        if not words:
            # 显示完成总结
            show_spelling_completion_summary()
            return

        current_word_attempts = 0  # 重置当前单词的尝试次数
        question = words[0]  # 取第一个单词，不立即移除
        question_text = question["mean"]
        correct_word = question["word"]
        
        # 获取当前单词的学习状态
        word_status = load_word_status(current_user).get(correct_word, {})
        error_count = word_status.get("error_count", 0)
        
        # 获取单词首字母和长度作为提示
        first_letter = correct_word[0] if correct_word else ""
        word_length = len(correct_word)
        hint_text = f"提示: 首字母 '{first_letter}', 单词长度 {word_length} 个字母"

        for widget in quiz_window.winfo_children():
            widget.destroy()

        main_frame = tk.Frame(quiz_window)
        main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))

        # 显示单词状态和进度信息
        status_frame = tk.Frame(main_frame)
        status_frame.pack(pady=int(20 * metrics.scale))
        
        progress_text = f"剩余单词: {len(words)} | 当前单词错误次数: {error_count}"
        if current_word_attempts > 0:
            progress_text += f" | 本次尝试: {current_word_attempts}/{max_attempts}"
        
        tk.Label(status_frame, text=progress_text, font=get_font(12), fg="#666666").pack()

        header_frame = tk.Frame(main_frame)
        header_frame.pack(pady=int(80 * metrics.scale))
        tk.Label(header_frame, text=f"单词释义：{question_text}", font=TITLE_FONT).pack()
        
        # 显示提示信息
        hint_label = tk.Label(header_frame, text=hint_text, font=get_font(12), fg="#1E90FF")
        hint_label.pack(pady=int(10 * metrics.scale))
        
        # 增加显示更多提示的按钮和标签
        hint_more_frame = tk.Frame(header_frame)
        hint_more_frame.pack(pady=int(5 * metrics.scale))
        
        more_hint_label = tk.Label(hint_more_frame, text="", font=get_font(12), fg="#1E90FF")
        more_hint_label.pack(side=tk.TOP, pady=int(5 * metrics.scale))
        
        def show_more_hint():
            # 显示单词的前三个字母
            prefix = correct_word[:3] if len(correct_word) >= 3 else correct_word
            # 用星号替换剩余字母
            masked_word = prefix + "*" * (len(correct_word) - len(prefix))
            more_hint_label.config(text=f"更多提示: {masked_word}")
        
        hint_btn = tk.Button(hint_more_frame, text="显示更多提示", font=get_font(10),
                           bg="#1E90FF", fg="white", command=show_more_hint)
        hint_btn.pack(side=tk.TOP)

        input_frame = tk.Frame(main_frame)
        input_frame.pack(pady=int(60 * metrics.scale))
        entry = tk.Entry(input_frame, font=get_font(24), width=int(20 * metrics.scale))
        entry.pack(pady=int(30 * metrics.scale))
        entry.focus_set()
        
        # 错误反馈显示框架
        feedback_frame = tk.Frame(main_frame)
        feedback_frame.pack(pady=int(20 * metrics.scale))
        
        # 如果尝试次数达到上限，显示正确答案
        if current_word_attempts >= max_attempts:
            tk.Label(feedback_frame, text=f"正确答案：{correct_word}", 
                    font=get_font(16), fg="#F56C6C").pack()

        def flash_green_and_continue():
            """输入框背景闪烁绿色并自动跳转"""
            original_bg = entry.cget("bg")
            entry.config(bg="#67C23A")  # 绿色背景
            quiz_window.after(300, lambda: entry.config(bg=original_bg))  # 300ms后恢复
            quiz_window.after(800, move_to_next_word)  # 800ms后跳转下一题

        def show_letter_feedback(user_input, correct_word):
            """显示字母级别的错误反馈"""
            # 清空原有反馈
            for widget in feedback_frame.winfo_children():
                widget.destroy()
            
            # 创建带颜色的标签
            feedback_label_frame = tk.Frame(feedback_frame)
            feedback_label_frame.pack()
            
            tk.Label(feedback_label_frame, text="拼写反馈：", font=get_font(14)).pack(side=tk.LEFT)
            
            # 解析并显示带颜色的文字
            for i in range(max(len(user_input), len(correct_word))):
                if i < len(user_input) and i < len(correct_word):
                    if user_input[i].lower() == correct_word[i].lower():
                        tk.Label(feedback_label_frame, text=user_input[i], font=get_font(16), 
                                fg="#67C23A", bg="#E8F5E8").pack(side=tk.LEFT, padx=1)
                    else:
                        tk.Label(feedback_label_frame, text=user_input[i], font=get_font(16), 
                                fg="#F56C6C", bg="#FFEBEE").pack(side=tk.LEFT, padx=1)
                elif i >= len(user_input):
                    tk.Label(feedback_label_frame, text="_", font=get_font(16), 
                            fg="#F56C6C", bg="#FFEBEE").pack(side=tk.LEFT, padx=1)
                elif i >= len(correct_word):
                    tk.Label(feedback_label_frame, text=user_input[i], font=get_font(16), 
                            fg="#F56C6C", bg="#FFEBEE").pack(side=tk.LEFT, padx=1)

        def move_to_next_word():
            """移动到下一个单词"""
            nonlocal words
            words.pop(0)  # 移除当前单词
            next_question()

        def skip_current_word():
            """跳过当前单词"""
            if messagebox.askyesno("确认跳过", f"确定要跳过单词 '{correct_word}' 吗？"):
                # 记录跳过，视为错误
                record_user_training(current_user, question["word"], False, "跳过", question_text, "拼写题")
                update_word_status(current_user, question["word"], False)
                move_to_next_word()

        def check_answer():
            nonlocal current_word_attempts
            user_input = entry.get().strip()
            current_word_attempts += 1
            
            if user_input.lower() == question["word"].lower():
                messagebox.showinfo("结果", "拼写正确！")
                record_user_training(current_user, question["word"], True, user_input, question_text, "拼写题")
                # 更新单词状态为正确
                word_status = update_word_status(current_user, question["word"], True)
                
                # 检查是否已熟练
                if word_status["mastered"]:
                    messagebox.showinfo("恭喜", f"单词 '{question['word']}' 已熟练掌握！")
                
                # 重置连续错误计数
                if correct_word in consecutive_errors:
                    del consecutive_errors[correct_word]
                
                # 输入框闪烁绿色并自动跳转
                flash_green_and_continue()
                
            else:
                # 更新单词状态为错误
                update_word_status(current_user, question["word"], False)
                
                # 显示字母级别反馈
                show_letter_feedback(user_input, question["word"])
                
                record_user_training(current_user, question["word"], False, user_input, question_text, "拼写题")
                
                # 检查是否达到最大尝试次数
                if current_word_attempts >= max_attempts:
                    result = messagebox.askyesnocancel("拼写错误", 
                        f"已尝试 {max_attempts} 次。正确答案是：{question['word']}\n\n"
                        f"点击'是'继续下一个单词\n"
                        f"点击'否'再试一次\n"
                        f"点击'取消'跳过此单词")
                    
                    if result is True:  # 继续下一个单词
                        move_to_next_word()
                    elif result is False:  # 再试一次
                        current_word_attempts = 0  # 重置尝试次数
                        entry.delete(0, tk.END)
                        next_question()  # 重新显示当前问题
                    else:  # 跳过
                        skip_current_word()
                else:
                    messagebox.showerror("拼写错误", f"请再试一次！还有 {max_attempts - current_word_attempts} 次机会")
                    # 清空输入框，让用户重新输入
                    entry.delete(0, tk.END)
                    # 不调用next_question，保持在当前单词

        # 添加回车键提交功能
        entry.bind("<Return>", lambda event: check_answer())

        btn_frame = tk.Frame(main_frame)
        btn_frame.pack(pady=int(40 * metrics.scale))
        tk.Button(btn_frame, text="提交", font=BUTTON_FONT,
                  command=check_answer).pack(side=tk.LEFT, padx=int(20 * metrics.scale))
        tk.Button(btn_frame, text="跳过", font=BUTTON_FONT, bg="#FFA500", fg="white",
                  command=skip_current_word).pack(side=tk.LEFT, padx=int(20 * metrics.scale))
        tk.Button(btn_frame, text="返回", font=BUTTON_FONT,
                  command=lambda: [quiz_window.destroy(), parent_window.deiconify()]).pack(side=tk.RIGHT)

    def show_spelling_completion_summary():
        """显示拼写训练完成总结"""
        for widget in quiz_window.winfo_children():
            widget.destroy()
        
        main_frame = tk.Frame(quiz_window)
        main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))
        
        tk.Label(main_frame, text="拼写训练完成！", font=TITLE_FONT).pack(pady=int(40 * metrics.scale))
        
        # 显示学习状态统计
        status_data = load_word_status(current_user)
        mastered_count = sum(1 for status in status_data.values() if status["mastered"])
        total_learned = len(status_data)
        
        stats_text = (
            f"已熟练单词：{mastered_count} 个\n"
            f"总学习单词：{total_learned} 个\n"
            f"掌握率：{(mastered_count/total_learned*100):.1f}%" if total_learned > 0 else "掌握率：0%"
        )
        
        tk.Label(main_frame, text=stats_text, font=get_font(16), justify=tk.CENTER).pack(pady=int(20 * metrics.scale))
        
        btn_frame = tk.Frame(main_frame)
        btn_frame.pack(pady=int(40 * metrics.scale))
        
        tk.Button(btn_frame, text="继续练习", font=BUTTON_FONT, bg="#409EFF", fg="white",
                  command=lambda: start_spelling_quiz(parent_window)).pack(side=tk.LEFT, padx=int(20 * metrics.scale))
        tk.Button(btn_frame, text="返回主菜单", font=BUTTON_FONT,
                  command=lambda: [quiz_window.destroy(), open_game_menu()]).pack(side=tk.RIGHT, padx=int(20 * metrics.scale))
    
    next_question()

def start_error_review_mode(error_words, parent_window):
    """错题重点复习模式"""
    if not error_words:
        messagebox.showinfo("提示", "没有需要复习的错题")
        return
    
    if messagebox.askyesno("重点复习", f"开始重点复习模式？\n将复习 {len(error_words)} 个错题单词"):
        parent_window.withdraw()

        # 按优先级排序，优先练习高错误率单词
        sorted_words = sorted(error_words, key=lambda x: x["priority"], reverse=True)
        
        # 创建复习单词列表（只包含单词名）
        review_word_names = [w["word"] for w in sorted_words[:20]]  # 限制在前20个高优先级单词
        
        # 启动拼写练习，使用错题单词
        start_error_spelling_review(review_word_names, parent_window)

def start_error_spelling_review(word_names, parent_window):
    """错题拼写复习"""
    review_window = tk.Toplevel(root)
    review_window.attributes("-fullscreen", True)
    review_window.title("错题重点复习")
    
    # 获取单词详细信息
    folder_path = "cet-4_json"
    all_words = load_cet4_words(folder_path)
    word_dict = {w["word"]: w for w in all_words}
    
    review_words = []
    for name in word_names:
        if name in word_dict:
            review_words.append(word_dict[name])
    
    if not review_words:
        messagebox.showerror("错误", "未找到复习单词信息")
        review_window.destroy()
        parent_window.deiconify()
        return

    current_index = 0
    correct_count = 0
    
    def next_review():
        nonlocal current_index, correct_count
        
        if current_index >= len(review_words):
            show_review_summary()
            return
        
        word_data = review_words[current_index]
        
        for widget in review_window.winfo_children():
            widget.destroy()
        
        main_frame = tk.Frame(review_window)
        main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))
        
        # 进度显示
        progress_frame = tk.Frame(main_frame)
        progress_frame.pack(pady=int(20 * metrics.scale))
        
        progress_text = f"错题复习进度：{current_index + 1}/{len(review_words)}"
        if current_index > 0:
            accuracy = (correct_count / current_index * 100)
            progress_text += f" | 正确率：{accuracy:.1f}%"
        
        tk.Label(progress_frame, text=progress_text, font=get_font(12), fg="#666666").pack()
        
        # 显示当前单词的错误历史
        word_status = load_word_status(current_user).get(word_data["word"], {})
        error_count = word_status.get("error_count", 0)
        
        tk.Label(progress_frame, text=f"此单词历史错误次数：{error_count}", 
                font=get_font(10), fg="#F56C6C").pack()
        
        # 题目显示
        header_frame = tk.Frame(main_frame)
        header_frame.pack(pady=int(60 * metrics.scale))
        
        tk.Label(header_frame, text="错题重点复习", font=TITLE_FONT).pack()
        tk.Label(header_frame, text=f"释义：{word_data['mean']}", font=get_font(16)).pack(pady=int(20 * metrics.scale))
        
        # 提示
        hint_text = f"提示: 首字母 '{word_data['word'][0]}', 长度 {len(word_data['word'])} 字母"
        tk.Label(header_frame, text=hint_text, font=get_font(12), fg="#1E90FF").pack()

        # 输入框
        input_frame = tk.Frame(main_frame)
        input_frame.pack(pady=int(40 * metrics.scale))
        
        entry = tk.Entry(input_frame, font=get_font(24), width=int(20 * metrics.scale))
        entry.pack()
        entry.focus_set()
        
        def check_review_answer():
            nonlocal current_index, correct_count
            user_input = entry.get().strip()
            
            if user_input.lower() == word_data["word"].lower():
                correct_count += 1
                messagebox.showinfo("正确", "拼写正确！继续加油！")
                update_word_status(current_user, word_data["word"], True)
            else:
                messagebox.showerror("继续努力", f"拼写错误！正确答案：{word_data['word']}")
                update_word_status(current_user, word_data["word"], False)
            
            current_index += 1
            next_review()
        
        entry.bind("<Return>", lambda e: check_review_answer())
        
        btn_frame = tk.Frame(main_frame)
        btn_frame.pack(pady=int(40 * metrics.scale))
        
        tk.Button(btn_frame, text="提交", font=BUTTON_FONT, command=check_review_answer).pack(side=tk.LEFT, padx=int(20 * metrics.scale))
        tk.Button(btn_frame, text="跳过", font=BUTTON_FONT, bg="#FFA500", fg="white",
                 command=lambda: [setattr(sys.modules[__name__], 'current_index', current_index + 1), next_review()]).pack(side=tk.LEFT, padx=int(20 * metrics.scale))
        tk.Button(btn_frame, text="结束复习", font=BUTTON_FONT, bg="#F56C6C", fg="white",
                 command=lambda: [review_window.destroy(), parent_window.deiconify()]).pack(side=tk.RIGHT, padx=int(20 * metrics.scale))
    
    def show_review_summary():
        for widget in review_window.winfo_children():
            widget.destroy()
        
        main_frame = tk.Frame(review_window)
        main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))
        
        tk.Label(main_frame, text="错题复习完成！", font=TITLE_FONT).pack(pady=int(40 * metrics.scale))
        
        accuracy = (correct_count / len(review_words) * 100) if review_words else 0
        
        result_text = (
            f"复习单词数：{len(review_words)}\n"
            f"正确次数：{correct_count}\n"
            f"复习正确率：{accuracy:.1f}%"
        )
        
        tk.Label(main_frame, text=result_text, font=get_font(16), justify=tk.CENTER).pack(pady=int(20 * metrics.scale))
        
        if accuracy >= 80:
            tk.Label(main_frame, text="🎉 复习效果很好！", font=get_font(16), fg="#67C23A").pack()
        elif accuracy >= 60:
            tk.Label(main_frame, text="👍 有所进步，继续努力！", font=get_font(16), fg="#409EFF").pack()
        else:
            tk.Label(main_frame, text="💪 需要更多练习", font=get_font(16), fg="#E6A23C").pack()

    btn_frame = tk.Frame(main_frame)
    btn_frame.pack(pady=int(40 * metrics.scale))
    
    tk.Button(btn_frame, text="再次复习", font=BUTTON_FONT, bg="#409EFF", fg="white",
             command=lambda: start_error_spelling_review(word_names, parent_window)).pack(side=tk.LEFT, padx=int(20 * metrics.scale))
    tk.Button(btn_frame, text="返回错题本", font=BUTTON_FONT,
             command=lambda: [review_window.destroy(), parent_window.deiconify()]).pack(side=tk.RIGHT, padx=int(20 * metrics.scale))
    
    next_review()




# ------------------ 单词闯关打卡功能 ------------------
def start_word_challenge(parent_window=None):
    if parent_window:
        parent_window.withdraw()
    
    # 全局变量用于跟踪状态
    challenge_words = []      # 本次挑战的50个单词
    current_phase = "study"   # 当前阶段：study, choice, hint_spelling, no_hint_spelling
    correct_count = 0         # 当前阶段累计答对的题目数
    total_answered = 0        # 总答题数
    total_correct = 0         # 总正确数
    wrong_streak = 0          # 连续答错计数
    wrong_count = 0           # 当前阶段累计答错的题目数
    current_word_index = 0    # 当前单词索引
    consecutive_errors = {}   # 字典存储每个单词的连续错误次数
    
    # 创建主窗口
    challenge_window = tk.Toplevel(root)
    challenge_window.attributes("-fullscreen", True)
    challenge_window.title("单词闯关打卡")
    
    # 选择50个单词
    def select_challenge_words():
        nonlocal challenge_words
        folder_path = "cet-4_json"
        all_words = load_cet4_words(folder_path)
        random.shuffle(all_words)
        challenge_words = all_words[:50]
    
    # 显示学习页面
    def show_study_page():
        nonlocal current_phase
        current_phase = "study"
        
        # 清空当前窗口内容
        for widget in challenge_window.winfo_children():
            widget.destroy()
        
        # 创建主标题
        main_label = tk.Label(challenge_window, text="单词闯关打卡 - 学习阶段", font=TITLE_FONT)
        main_label.pack(pady=int(20 * metrics.scale))
        
        # 顶部按钮框架
        btn_frame = tk.Frame(challenge_window)
        btn_frame.pack(fill=tk.X, pady=int(15 * metrics.scale), padx=int(30 * metrics.scale))
        
        # 两个按钮并排放置在上方
        tk.Button(btn_frame, text="返回主菜单", font=BUTTON_FONT, bg="#F56C6C", fg="white", 
                  padx=int(20 * metrics.scale), pady=int(8 * metrics.scale),
                  command=lambda: [challenge_window.destroy(), open_game_menu()]).pack(side=tk.LEFT)
        
        tk.Button(btn_frame, text="学习完成，开始答题", font=BUTTON_FONT, bg="#409EFF", fg="white",
                  padx=int(20 * metrics.scale), pady=int(8 * metrics.scale),
                  command=start_choice_phase).pack(side=tk.RIGHT)
        
        tip_label = tk.Label(challenge_window, 
                            text="请记忆以下50个单词，学习完成后点击上方按钮开始答题",
                            font=get_font(14))
        tip_label.pack(pady=int(10 * metrics.scale))
        
        # 创建三列框架
        columns_frame = tk.Frame(challenge_window)
        columns_frame.pack(fill=tk.BOTH, expand=True, padx=int(30 * metrics.scale), pady=int(20 * metrics.scale))
        
        # 分割单词列表为三部分
        words_per_column = len(challenge_words) // 3
        remainder = len(challenge_words) % 3
        
        # 确定每列单词数量
        col1_count = words_per_column + (1 if remainder > 0 else 0)
        col2_count = words_per_column + (1 if remainder > 1 else 0)
        col3_count = words_per_column
        
        # 分配单词到三列
        col1_words = challenge_words[:col1_count]
        col2_words = challenge_words[col1_count:col1_count+col2_count]
        col3_words = challenge_words[col1_count+col2_count:]
        
        # 创建三列框架
        left_frame = tk.Frame(columns_frame)
        left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=int(5 * metrics.scale))
        
        middle_frame = tk.Frame(columns_frame)
        middle_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=int(5 * metrics.scale))
        
        right_frame = tk.Frame(columns_frame)
        right_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=int(5 * metrics.scale))
        
        # 创建三列文本
        col1_text = ""
        for idx, word in enumerate(col1_words):
            col1_text += f"{idx+1}. {word['word']} {word['phonetic_symbol']}\n   {word['mean']}\n\n"
        
        col2_text = ""
        for idx, word in enumerate(col2_words):
            col2_text += f"{idx+col1_count+1}. {word['word']} {word['phonetic_symbol']}\n   {word['mean']}\n\n"
        
        col3_text = ""
        for idx, word in enumerate(col3_words):
            col3_text += f"{idx+col1_count+col2_count+1}. {word['word']} {word['phonetic_symbol']}\n   {word['mean']}\n\n"
        
        # 显示三列单词
        left_label = tk.Label(left_frame, text=col1_text, font=get_font(12), 
                             justify=tk.LEFT, wraplength=int(280 * metrics.scale))
        left_label.pack(pady=int(10 * metrics.scale), anchor=tk.NW)
        
        middle_label = tk.Label(middle_frame, text=col2_text, font=get_font(12), 
                               justify=tk.LEFT, wraplength=int(280 * metrics.scale))
        middle_label.pack(pady=int(10 * metrics.scale), anchor=tk.NW)
        
        right_label = tk.Label(right_frame, text=col3_text, font=get_font(12), 
                               justify=tk.LEFT, wraplength=int(280 * metrics.scale))
        right_label.pack(pady=int(10 * metrics.scale), anchor=tk.NW)
    
    # 开始选择题阶段
    def start_choice_phase():
        nonlocal current_phase, correct_count, wrong_streak, wrong_count, current_word_index
        current_phase = "choice"
        correct_count = 0
        wrong_streak = 0
        wrong_count = 0
        current_word_index = 0
        show_next_question()
    
    # 开始提示拼写阶段
    def start_hint_spelling_phase():
        nonlocal current_phase, correct_count, wrong_streak, wrong_count, current_word_index
        current_phase = "hint_spelling"
        correct_count = 0
        wrong_streak = 0
        wrong_count = 0
        current_word_index = 0
        show_next_question()
    
    # 开始无提示拼写阶段
    def start_no_hint_spelling_phase():
        nonlocal current_phase, correct_count, wrong_streak, wrong_count, current_word_index
        current_phase = "no_hint_spelling"
        correct_count = 0
        wrong_streak = 0
        wrong_count = 0
        current_word_index = 0
        show_next_question()
    
    # 显示下一个问题
    def show_next_question():
        nonlocal current_word_index
        
        # 每次都从50个单词中随机选择一个，不使用固定顺序
        current_word_index = random.randint(0, len(challenge_words) - 1)
        current_word = challenge_words[current_word_index]
        
        # 清空当前窗口内容
        for widget in challenge_window.winfo_children():
            widget.destroy()
        
        main_frame = tk.Frame(challenge_window)
        main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))
        
        # 显示当前阶段和进度
        header_frame = tk.Frame(main_frame)
        header_frame.pack(pady=int(40 * metrics.scale))
        
        phase_text = {
            "choice": "选择题阶段",
            "hint_spelling": "提示拼写阶段",
            "no_hint_spelling": "无提示拼写阶段"
        }
        
        tk.Label(header_frame, text=f"单词闯关打卡 - {phase_text[current_phase]}", 
                 font=TITLE_FONT).pack()
        
        progress_frame = tk.Frame(header_frame)
        progress_frame.pack(pady=int(10 * metrics.scale))
        
        # 显示累计答对/答错计数和总体正确率
        correct_ratio = (total_correct / total_answered * 100) if total_answered > 0 else 0
        tk.Label(progress_frame, text=f"本阶段累计答对: {correct_count}/5", 
                 font=get_font(12), fg="#67C23A").pack(side=tk.LEFT, padx=int(10 * metrics.scale))
        tk.Label(progress_frame, text=f"累计答错: {wrong_count}/5", 
                 font=get_font(12), fg="#F56C6C").pack(side=tk.LEFT, padx=int(10 * metrics.scale))
        tk.Label(progress_frame, text=f"已答题: {total_answered}题", 
                 font=get_font(12), fg="#666666").pack(side=tk.LEFT, padx=int(10 * metrics.scale))
        tk.Label(progress_frame, text=f"正确率: {correct_ratio:.1f}%", 
                 font=get_font(12), fg="#409EFF").pack(side=tk.LEFT, padx=int(10 * metrics.scale))
        
        # 根据当前阶段显示不同的题目界面
        if current_phase == "choice":
            show_choice_question(main_frame, current_word)
        elif current_phase == "hint_spelling":
            show_hint_spelling_question(main_frame, current_word)
        else:  # no_hint_spelling
            show_no_hint_spelling_question(main_frame, current_word)
    
    # 显示选择题
    def show_choice_question(parent_frame, word):
        question_text = word["mean"]
        correct_word = word["word"]
        
        # 生成干扰选项 - 从50个单词中随机选择3个不同的单词
        other_words = [w for w in challenge_words if w["word"] != correct_word]
        random.shuffle(other_words)
        distractors = other_words[:3]
        
        options = [correct_word] + [w["word"] for w in distractors]
        random.shuffle(options)  # 确保选项顺序随机
        
        # 显示题目
        question_frame = tk.Frame(parent_frame)
        question_frame.pack(pady=int(40 * metrics.scale))
        tk.Label(question_frame, text=f"单词释义：{question_text}", font=TITLE_FONT).pack()
        
        # 选项区域
        options_frame = tk.Frame(parent_frame)
        options_frame.pack(pady=int(40 * metrics.scale))
        
        for idx, option in enumerate(options):
            btn = tk.Button(options_frame, text=option, font=BUTTON_FONT,
                          width=int(20 * metrics.scale), height=int(2 * metrics.scale),
                          command=lambda opt=option: check_choice_answer(opt, correct_word))
            btn.grid(row=idx // 2, column=idx % 2, padx=int(30 * metrics.scale), pady=int(20 * metrics.scale))
        
        # 底部按钮
        btn_frame = tk.Frame(parent_frame)
        btn_frame.pack(pady=int(40 * metrics.scale))
        tk.Button(btn_frame, text="返回主菜单", font=BUTTON_FONT,
                  command=lambda: [challenge_window.destroy(), open_game_menu()]).pack()
    
    # 显示提示拼写题
    def show_hint_spelling_question(parent_frame, word):
        question_text = word["mean"]
        correct_word = word["word"]
        
        # 获取当前单词的连续错误次数
        current_errors = consecutive_errors.get(correct_word, 0)
        
        # 获取单词首字母和长度作为提示
        first_letter = correct_word[0] if correct_word else ""
        word_length = len(correct_word)
        hint_text = f"提示: 首字母 '{first_letter}', 单词长度 {word_length} 个字母"
        
        # 显示题目
        question_frame = tk.Frame(parent_frame)
        question_frame.pack(pady=int(40 * metrics.scale))
        tk.Label(question_frame, text=f"单词释义：{question_text}", font=TITLE_FONT).pack()
        tk.Label(question_frame, text=hint_text, font=get_font(12), fg="#1E90FF").pack(pady=int(10 * metrics.scale))
        
        # 增加显示更多提示的按钮和标签
        hint_more_frame = tk.Frame(question_frame)
        hint_more_frame.pack(pady=int(5 * metrics.scale))
        
        more_hint_label = tk.Label(hint_more_frame, text="", font=get_font(12), fg="#1E90FF")
        more_hint_label.pack(side=tk.TOP, pady=int(5 * metrics.scale))
        
        def show_more_hint():
            # 显示单词的前三个字母
            prefix = correct_word[:3] if len(correct_word) >= 3 else correct_word
            # 用星号替换剩余字母
            masked_word = prefix + "*" * (len(correct_word) - len(prefix))
            more_hint_label.config(text=f"更多提示: {masked_word}")
        
        hint_btn = tk.Button(hint_more_frame, text="显示更多提示", font=get_font(10),
                           bg="#1E90FF", fg="white", command=show_more_hint)
        hint_btn.pack(side=tk.TOP)
        
        # 如果连续错误两次，显示正确答案
        if current_errors >= 2:
            tk.Label(question_frame, text=f"正确答案：{correct_word}", 
                    font=get_font(16), fg="#F56C6C").pack(pady=int(5 * metrics.scale))
        
        # 输入区域
        input_frame = tk.Frame(parent_frame)
        input_frame.pack(pady=int(40 * metrics.scale))
        entry = tk.Entry(input_frame, font=get_font(20), width=int(20 * metrics.scale))
        entry.pack(pady=int(20 * metrics.scale))
        entry.focus_set()
        
        # 错误反馈显示框架
        feedback_frame = tk.Frame(parent_frame)
        feedback_frame.pack(pady=int(20 * metrics.scale))
        
        def flash_green_and_continue():
            """输入框背景闪烁绿色并自动跳转"""
            original_bg = entry.cget("bg")
            entry.config(bg="#67C23A")  # 绿色背景
            challenge_window.after(300, lambda: entry.config(bg=original_bg))  # 300ms后恢复
            challenge_window.after(800, show_next_question)  # 800ms后跳转下一题

        def show_letter_feedback(user_input, correct_word):
            """显示字母级别的错误反馈"""
            # 清空原有反馈
            for widget in feedback_frame.winfo_children():
                widget.destroy()
            
            # 创建带颜色的标签
            feedback_label_frame = tk.Frame(feedback_frame)
            feedback_label_frame.pack()
            
            tk.Label(feedback_label_frame, text="拼写反馈：", font=get_font(14)).pack(side=tk.LEFT)
            
            # 解析并显示带颜色的文字
            for i in range(max(len(user_input), len(correct_word))):
                if i < len(user_input) and i < len(correct_word):
                    if user_input[i].lower() == correct_word[i].lower():
                        tk.Label(feedback_label_frame, text=user_input[i], font=get_font(16), 
                                fg="#67C23A", bg="#E8F5E8").pack(side=tk.LEFT, padx=1)
                    else:
                        tk.Label(feedback_label_frame, text=user_input[i], font=get_font(16), 
                                fg="#F56C6C", bg="#FFEBEE").pack(side=tk.LEFT, padx=1)
                elif i >= len(user_input):
                    tk.Label(feedback_label_frame, text="_", font=get_font(16), 
                            fg="#F56C6C", bg="#FFEBEE").pack(side=tk.LEFT, padx=1)
                elif i >= len(correct_word):
                    tk.Label(feedback_label_frame, text=user_input[i], font=get_font(16), 
                            fg="#F56C6C", bg="#FFEBEE").pack(side=tk.LEFT, padx=1)
        
        # 添加回车键提交功能
        entry.bind("<Return>", lambda event: check_spelling_answer_with_feedback(entry.get(), correct_word, show_letter_feedback))
        
        # 按钮区域
        btn_frame = tk.Frame(parent_frame)
        btn_frame.pack(pady=int(40 * metrics.scale))
        tk.Button(btn_frame, text="提交", font=BUTTON_FONT,
                 command=lambda: check_spelling_answer_with_feedback(entry.get(), correct_word, show_letter_feedback)).pack(side=tk.LEFT, padx=int(20 * metrics.scale))
        tk.Button(btn_frame, text="返回主菜单", font=BUTTON_FONT,
                 command=lambda: [challenge_window.destroy(), open_game_menu()]).pack(side=tk.RIGHT, padx=int(20 * metrics.scale))
    
    # 显示无提示拼写题
    def show_no_hint_spelling_question(parent_frame, word):
        question_text = word["mean"]
        correct_word = word["word"]
        
        # 获取当前单词的连续错误次数
        current_errors = consecutive_errors.get(correct_word, 0)
        
        # 显示题目
        question_frame = tk.Frame(parent_frame)
        question_frame.pack(pady=int(40 * metrics.scale))
        tk.Label(question_frame, text=f"单词释义：{question_text}", font=TITLE_FONT).pack()
        tk.Label(question_frame, text="请拼写出对应的单词", font=get_font(12), fg="#666666").pack(pady=int(10 * metrics.scale))
        
        # 如果连续错误两次，显示正确答案
        if current_errors >= 2:
            tk.Label(question_frame, text=f"正确答案：{correct_word}", 
                    font=get_font(16), fg="#F56C6C").pack(pady=int(5 * metrics.scale))
        
        # 输入区域
        input_frame = tk.Frame(parent_frame)
        input_frame.pack(pady=int(40 * metrics.scale))
        entry = tk.Entry(input_frame, font=get_font(20), width=int(20 * metrics.scale))
        entry.pack(pady=int(20 * metrics.scale))
        entry.focus_set()
        
        # 错误反馈显示框架
        feedback_frame = tk.Frame(parent_frame)
        feedback_frame.pack(pady=int(20 * metrics.scale))
        
        def flash_green_and_continue():
            """输入框背景闪烁绿色并自动跳转"""
            original_bg = entry.cget("bg")
            entry.config(bg="#67C23A")  # 绿色背景
            challenge_window.after(300, lambda: entry.config(bg=original_bg))  # 300ms后恢复
            challenge_window.after(800, show_next_question)  # 800ms后跳转下一题

        def show_letter_feedback(user_input, correct_word):
            """显示字母级别的错误反馈"""
            # 清空原有反馈
            for widget in feedback_frame.winfo_children():
                widget.destroy()
            
            # 创建带颜色的标签
            feedback_label_frame = tk.Frame(feedback_frame)
            feedback_label_frame.pack()
            
            tk.Label(feedback_label_frame, text="拼写反馈：", font=get_font(14)).pack(side=tk.LEFT)
            
            # 解析并显示带颜色的文字
            for i in range(max(len(user_input), len(correct_word))):
                if i < len(user_input) and i < len(correct_word):
                    if user_input[i].lower() == correct_word[i].lower():
                        tk.Label(feedback_label_frame, text=user_input[i], font=get_font(16), 
                                fg="#67C23A", bg="#E8F5E8").pack(side=tk.LEFT, padx=1)
                    else:
                        tk.Label(feedback_label_frame, text=user_input[i], font=get_font(16), 
                                fg="#F56C6C", bg="#FFEBEE").pack(side=tk.LEFT, padx=1)
                elif i >= len(user_input):
                    tk.Label(feedback_label_frame, text="_", font=get_font(16), 
                            fg="#F56C6C", bg="#FFEBEE").pack(side=tk.LEFT, padx=1)
                elif i >= len(correct_word):
                    tk.Label(feedback_label_frame, text=user_input[i], font=get_font(16), 
                            fg="#F56C6C", bg="#FFEBEE").pack(side=tk.LEFT, padx=1)
        
        # 添加回车键提交功能
        entry.bind("<Return>", lambda event: check_spelling_answer_with_feedback(entry.get(), correct_word, show_letter_feedback))
        
        # 按钮区域
        btn_frame = tk.Frame(parent_frame)
        btn_frame.pack(pady=int(40 * metrics.scale))
        tk.Button(btn_frame, text="提交", font=BUTTON_FONT,
                 command=lambda: check_spelling_answer_with_feedback(entry.get(), correct_word, show_letter_feedback)).pack(side=tk.LEFT, padx=int(20 * metrics.scale))
        tk.Button(btn_frame, text="返回主菜单", font=BUTTON_FONT,
                 command=lambda: [challenge_window.destroy(), open_game_menu()]).pack(side=tk.RIGHT, padx=int(20 * metrics.scale))
    
    # 检查选择题答案
    def check_choice_answer(selected_word, correct_word):
        nonlocal correct_count, wrong_streak, wrong_count, current_word_index, total_answered, total_correct
        
        total_answered += 1
        current_word_index += 1
        
        # 标准化输入，忽略大小写和首尾空格
        if selected_word.strip().lower() == correct_word.strip().lower():
            messagebox.showinfo("结果", "回答正确！")
            total_correct += 1
            correct_count += 1 # 累计答对数加1
            
            # 记录训练
            record_user_training(current_user, correct_word, True, selected_word, challenge_words[current_word_index-1]["mean"], "闯关-选择题")
            
            # 检查是否累计答对达到5题
            if correct_count >= 5:
                messagebox.showinfo("阶段完成", "恭喜你累计答对5道题！即将进入提示拼写阶段。")
                start_hint_spelling_phase()
                return
        else:
            messagebox.showerror("结果", f"回答错误！正确答案是：{correct_word}")
            wrong_count += 1  # 累计答错数加1
            
            # 记录训练
            record_user_training(current_user, correct_word, False, selected_word, challenge_words[current_word_index-1]["mean"], "闯关-选择题")
            
            # 检查是否需要提示复习
            if wrong_count >= 5:
                if messagebox.askyesno("提示", "你已经累计答错5题，是否需要再次学习单词？"):
                    wrong_count = 0  # 重置累计答错数
                    # 保存当前阶段
                    temp_phase = current_phase
                    # 显示学习页面
                    show_study_page()
                    # 添加直接返回当前阶段的按钮
                    add_return_to_phase_button(temp_phase)
                    return
                else:
                    wrong_count = 0  # 用户选择继续，重置累计答错数
        
        # 显示下一题
        show_next_question()
    
    # 显示最终结果
    def show_final_result():
        # 清空当前窗口内容
        for widget in challenge_window.winfo_children():
            widget.destroy()
        
        main_frame = tk.Frame(challenge_window)
        main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))
        
        # 显示标题
        header_frame = tk.Frame(main_frame)
        header_frame.pack(pady=int(40 * metrics.scale))
        tk.Label(header_frame, text="单词闯关挑战完成！", font=TITLE_FONT).pack()
        
        # 计算正确率
        correct_ratio = (total_correct / total_answered * 100) if total_answered > 0 else 0
        
        # 显示结果统计
        result_frame = tk.Frame(main_frame)
        result_frame.pack(pady=int(40 * metrics.scale))
        
        stats_text = (
            f"恭喜你完成了所有闯关阶段！\n\n"
            f"总答题数：{total_answered}题\n"
            f"正确题数：{total_correct}题\n"
            f"错误题数：{total_answered - total_correct}题\n"
            f"总正确率：{correct_ratio:.2f}%\n\n"
            f"继续加油，不断提升你的英语词汇量！"
        )
        
        tk.Label(result_frame, text=stats_text, font=get_font(16), justify=tk.LEFT).pack()
        
        # 底部按钮
        btn_frame = tk.Frame(main_frame)
        btn_frame.pack(pady=int(40 * metrics.scale))
        
        tk.Button(btn_frame, text="再来一次", font=BUTTON_FONT, bg="#409EFF", fg="white",
                 padx=int(30 * metrics.scale), pady=int(8 * metrics.scale),
                 command=lambda: [select_challenge_words(), show_study_page()]).pack(side=tk.LEFT, padx=int(20 * metrics.scale))
        
        tk.Button(btn_frame, text="返回主菜单", font=BUTTON_FONT, bg="#F56C6C", fg="white",
                 padx=int(30 * metrics.scale), pady=int(8 * metrics.scale),
                 command=lambda: [challenge_window.destroy(), open_game_menu()]).pack(side=tk.RIGHT, padx=int(20 * metrics.scale))
    
    # 添加一个函数来在学习页面中添加返回指定阶段的按钮
    def add_return_to_phase_button(phase):
        # 找到按钮框架
        for widget in challenge_window.winfo_children():
            if isinstance(widget, tk.Frame) and len(widget.winfo_children()) > 0:
                if isinstance(widget.winfo_children()[0], tk.Button):
                    btn_frame = widget
                    break
        
        # 更改"学习完成，开始答题"按钮的行为，使其返回到之前的阶段
        for widget in btn_frame.winfo_children():
            if isinstance(widget, tk.Button) and widget.cget("bg") == "#409EFF":
                widget.config(text="继续当前阶段答题", 
                              command=lambda p=phase: resume_phase(p))
                break

    # 恢复到指定阶段
    def resume_phase(phase):
        nonlocal current_phase
        current_phase = phase
        
        if phase == "choice":
            # 恢复到选择题阶段
            start_choice_phase()
        elif phase == "hint_spelling":
            # 恢复到提示拼写阶段
            start_hint_spelling_phase()
        elif phase == "no_hint_spelling":
            # 恢复到无提示拼写阶段
            start_no_hint_spelling_phase()
    
    # 初始化并开始显示
    select_challenge_words()
    show_study_page()




# ------------------ 单词状态管理系统 ------------------
def load_word_status(username):
    """加载用户的单词学习状态"""
    ensure_training_data_folder()
    file_path = f"training_data/word_status_{username}.json"
    if not os.path.exists(file_path):
        with open(file_path, "w") as file:
            json.dump({}, file)
    with open(file_path, "r") as file:
        return json.load(file)

def save_word_status(username, status_data):
    """保存用户的单词学习状态"""
    ensure_training_data_folder()
    file_path = f"training_data/word_status_{username}.json"
    with open(file_path, "w") as file:
        json.dump(status_data, file, indent=4)

def update_word_status(username, word, is_correct):
    """更新单词状态"""
    status_data = load_word_status(username)
    
    if word not in status_data:
        status_data[word] = {
            "correct_count": 0,
            "error_count": 0,
            "mastered": False,
            "last_attempt": datetime.now().isoformat(),
            "review_priority": 1.0
        }
    
    if is_correct:
        status_data[word]["correct_count"] += 1
        # 连续正确3次标记为已熟练
        if status_data[word]["correct_count"] >= 3:
            status_data[word]["mastered"] = True
            status_data[word]["review_priority"] = 0.1  # 降低复习优先级
    else:
        status_data[word]["error_count"] += 1
        status_data[word]["mastered"] = False
        # 错误次数越多，复习优先级越高
        status_data[word]["review_priority"] = min(5.0, 1.0 + status_data[word]["error_count"] * 0.5)
    
    status_data[word]["last_attempt"] = datetime.now().isoformat()
    save_word_status(username, status_data)
    return status_data[word]

def get_review_words(username, limit=50):
    """获取需要复习的单词列表，按错误次数和优先级排序"""
    status_data = load_word_status(username)
    review_words = []
    
    for word, status in status_data.items():
        if not status["mastered"] and status["error_count"] > 0:
            review_words.append({
                "word": word,
                "error_count": status["error_count"],
                "priority": status["review_priority"]
            })
    
    # 按优先级和错误次数排序
    review_words.sort(key=lambda x: (x["priority"], x["error_count"]), reverse=True)
    return review_words[:limit]

def get_adaptive_word_list(username, all_words, limit=50):
    """根据学习状态动态选择单词列表"""
    status_data = load_word_status(username)
    
    # 分类单词
    review_words = []     # 需要复习的单词
    new_words = []        # 未学过的单词
    mastered_words = []   # 已熟练的单词
    
    for word_data in all_words:
        word = word_data["word"]
        if word in status_data:
            if status_data[word]["mastered"]:
                mastered_words.append(word_data)
            else:
                review_words.append((word_data, status_data[word]["review_priority"]))
        else:
            new_words.append(word_data)
    
    # 按优先级排序复习单词
    review_words.sort(key=lambda x: x[1], reverse=True)
    review_words = [item[0] for item in review_words]
    
    # 动态分配比例：复习单词70%，新单词30%
    review_count = min(int(limit * 0.7), len(review_words))
    new_count = min(limit - review_count, len(new_words))
    
    selected_words = review_words[:review_count] + new_words[:new_count]
    random.shuffle(selected_words)
    
    return selected_words[:limit]




# ------------------ 主程序入口 ------------------
if __name__ == "__main__":
    root = tk.Tk()
    root.title("英语单词训练系统")
    root.attributes("-fullscreen", True)
    root.bind("<F11>", toggle_fullscreen)
    root.bind("<Escape>", end_fullscreen)

    main_frame = tk.Frame(root)
    main_frame.pack(expand=True, fill=tk.BOTH, padx=int(200 * metrics.scale), pady=int(100 * metrics.scale))

    tk.Label(main_frame, text="CET-4 英语单词训练系统", font=TITLE_FONT).pack(pady=int(60 * metrics.scale))

    btn_frame = tk.Frame(main_frame)
    btn_frame.pack(pady=int(40 * metrics.scale))

    tk.Button(btn_frame, text="注册", font=BUTTON_FONT,
              command=register_user).pack(side=tk.LEFT, padx=int(20 * metrics.scale))
    tk.Button(btn_frame, text="登录", font=BUTTON_FONT,
              command=login_user).pack(side=tk.LEFT, padx=int(20 * metrics.scale))
    tk.Button(btn_frame, text="忘记密码", font=BUTTON_FONT,
              command=forgot_password).pack(side=tk.LEFT, padx=int(20 * metrics.scale))

    exit_frame = tk.Frame(main_frame)
    exit_frame.pack(pady=int(60 * metrics.scale))
    tk.Button(exit_frame, text="退出系统", font=BUTTON_FONT,
              command=root.destroy).pack()

    root.mainloop()
    
    # 安全退出处理
    try:
        # 确保所有窗口都被正确销毁
        for widget in root.winfo_children():
            if hasattr(widget, 'destroy'):
                widget.destroy()
        root.quit()
        root.destroy()
    except Exception as e:
        # 忽略退出时的主题错误
        pass